package com.leenmvc.core.utils.thread.runnables;

import com.leenmvc.core.dao.communal.BaseDao;
import com.leenmvc.core.dao.mysql.MysqlBaseDaoImpl;
import com.leenmvc.core.security.entity.core.SysLogError;
import com.leenmvc.core.security.entity.core.SysLogOperation;
import com.leenmvc.core.security.entity.core.SysLogSql;
import com.leenmvc.core.utils.logger.LogEntityPool;
import com.leenmvc.core.utils.thread.ThreadLocalManager;
import com.leenmvc.core.utils.unique.SnowFlake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;


public class LogToDb implements Runnable {

    private final static Logger logger = LoggerFactory.getLogger(LogToDb.class);

    private BaseDao baseDao = MysqlBaseDaoImpl.getInstance();

    /**
     * 将要被添加的操作日志
     */
    private static Queue<SysLogOperation> logQueue = new LinkedBlockingQueue<SysLogOperation>();

    /**
     * 将要被添加的sql日志
     */
    private static Queue<SysLogSql> sqlQueue = new LinkedBlockingQueue<SysLogSql>();

    /**
     * 将要被添加的异常日志
     */
    private static Queue<SysLogError> errorQueue = new LinkedBlockingQueue<SysLogError>();

    @Override
    public void run() {
        Thread.currentThread().setName("thread-logTodb");
        ThreadLocalManager.setIsLog(1);
        while (true) {
            try {
                for (int i = 0; i < logQueue.size(); i++) {
                    SysLogOperation sysLog = logQueue.poll();
                    sysLog.setId(SnowFlake.generateId());
                    if (!baseDao.insert(sysLog)) {
                        logger.warn("插入到操作日志表失败！失败的操作为: {}", sysLog.getOperation());
                    }
                }

                for (int i = 0; i < sqlQueue.size(); i++) {
                    SysLogSql sqlLog = sqlQueue.poll();
                    sqlLog.setId(SnowFlake.generateId());
                    if (!baseDao.insert(sqlLog)) {
                        logger.warn("插入到sql日志表失败！插入失败的sql为：{}", sqlLog.getSqlStr());
                    } else {
                        LogEntityPool.closeLogSql(sqlLog);
                    }
                }

                for (int i = 0; i < errorQueue.size(); i++) {
                    SysLogError errorLog = errorQueue.poll();
                    errorLog.setId(SnowFlake.generateId());
                    if (!baseDao.insert(errorLog)) {
                        logger.error("插入到异常日志表失败！详细信息为: {}", errorLog.getErrorInfo());
                    }
                }

                Thread.sleep(5);
            } catch (InterruptedException e) {
                logger.error(e.getMessage(), e);
            } catch (Exception ex) {
                logger.warn(ex.getMessage(), ex);
            }
        }
    }

    public static void addOperation(SysLogOperation log) {
        logQueue.add(log);
    }

    public static void addSqllog(SysLogSql log) {
        sqlQueue.add(log);
    }

    public static void addErrorlog(SysLogError log) {
        errorQueue.add(log);
    }

}
